package com.example.easyrpc.server;

import com.example.easyrpc.model.RpcRequest;
import com.example.easyrpc.model.RpcResponse;
import com.example.easyrpc.register.LocalRegister;
import com.example.easyrpc.serializer.JdkSerializer;
import com.example.easyrpc.serializer.Serializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;


//反序列化请求获得参数
//根据获得的参数从本地注册器获得服务
//通过反射机制调用方法，获得结果
//对结果进行封装和序列化，写入响应中返回
public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest request) {
        //序列化器
        final Serializer serializer = new JdkSerializer();

        //记录日志
        System.out.println("收到请求:" + request.method() + " " + request.uri());

        request.bodyHandler(body -> {
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                //反序列化请求
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            RpcResponse rpcResponse = new RpcResponse();

            if (rpcRequest == null) {
                rpcResponse.setMessage("请求为空");
                doResponse(rpcResponse, request, serializer);
                return;
            }

            System.out.println("请求服务名:" + rpcRequest.getServiceName() + " " + "方法名" + rpcRequest.getMethodName());


            try {
                //根据服务名从本地注册器获得服务
                Class<?> serviceClass = LocalRegister.get(rpcRequest.getServiceName());
                Method method = serviceClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getArgTypes());
                Object result = method.invoke(serviceClass.newInstance(), rpcRequest.getArgs());
                //封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
            doResponse(rpcResponse, request, serializer);
        });
    }

    /**
     * 将结果包装序列化后写入响应中
     * @param rpcResponse
     * @param request
     * @param serializer
     */
    public void doResponse(RpcResponse rpcResponse, HttpServerRequest request, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response().putHeader("content-type", "application/json");
        //序列化响应
        try {
            byte[] bytes = serializer.serialize(rpcResponse);
            //写入响应
            httpServerResponse.end(Buffer.buffer(bytes));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }

}
